﻿
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

using n_GUIcoder;
using n_GUIset;
using n_MyIns;
using n_FuncIns;
using System.Collections.Generic;
using n_HardModule;

using n_scommonEXPForm;

namespace n_EPanel
{
public class EPanel : Panel
{
	public delegate void D_ItemSelect( string Name, int Index );
	public D_ItemSelect ItemSelect;
	
	public delegate void D_MouseOnIndexChanged( int Index );
	public D_MouseOnIndexChanged MouseOnIndexChanged;
	
	Brush ABrush;
	Brush B_Brush;
	
	scommonEXPForm Owner;
	
	//是否显示模块类指令
	public bool ModInsPanelVisible;
	
	int MoveTick;
	bool MyClick;
	
	int MouseX;
	int MouseY;
	
	int MouseOnInsIndex;
	int MouseOnModIndex;
	int LastInsIndex;
	int LastModIndex;
	
	bool LeftPress;
	bool RightPress;
	
	public const int HeadHeight = 30;
	
	bool HeadPress;
	int lastX;
	int lastY;
	
	//-----------------------------
	//模块列表
	public const int ModWidth = 170;
	const int ModHeight = 44;
	public ModeItem[] ModList;
	int StartModY;
	int ModLength;
	int ModCY;
	int LastModY;
	
	ModeItem SelectedMod;
	
	//-----------------------------
	//指令列表
	const int InsPadding1 = 10;
	string[] List;
	MyIns[] C_MyInsList;
	int C_MyInsListLength;
	public int StartInsY;
	int LastInsY;
	
	//====================================================
	
	//构造函数
	public EPanel( scommonEXPForm o ) : base()
	{
		this.BorderStyle = BorderStyle.None;
		this.BackColor = Color.Black;
		
		SetStyle(ControlStyles.UserPaint |
		         ControlStyles.AllPaintingInWmPaint |
		         ControlStyles.OptimizedDoubleBuffer |
		         ControlStyles.ResizeRedraw |
		         ControlStyles.SupportsTransparentBackColor,true);
		
		//this.Dock = DockStyle.Fill;
		this.ImeMode = ImeMode.NoControl;
		
		this.MouseMove += new MouseEventHandler( UserMouseMove );
		this.MouseUp += new MouseEventHandler( UserMouseUp );
		this.MouseDown += new MouseEventHandler( UserMouseDown );
		this.MouseWheel += new MouseEventHandler( MyMouseWheel );
		
		Width = ModWidth + 645;
		Height = 500;
		
		Owner = o;
		
		ABrush = new SolidBrush( Color.FromArgb( 100, 100, 100, 200 ) );
		B_Brush = new SolidBrush( Color.FromArgb( 245, 245, 245 ) );
		
		C_MyInsList = new MyIns[ 200 ];
		C_MyInsListLength = 0;
		
		MyClick = false;
		
		StartInsY = 0;
		StartModY = 0;
		
		LastInsIndex = -1;
		LastModIndex = -1;
		
		ModList = new ModeItem[100];
	}
	
	//清空模块列表
	public void ClearModList()
	{
		ModLength = 0;
		ModCY = HeadHeight;
		StartModY = 0;
		SelectedMod = null;
	}
	
	//添加一个模块
	public void AddMod( string Name, Image img )
	{
		ModList[ModLength] = new ModeItem( img, Name, 0, ModCY, ModWidth, ModHeight );
		ModLength++;
		ModCY += ModHeight;
		
		if( ModLength == 1 ) {
			SelectedMod = ModList[0];
		}
	}
	
	//设置表达式集合
	public void SetExp( string[] s, List<string> PreType )
	{
		StartInsY = 0;
		
		List = s;
		MouseOnInsIndex = -1;
		C_MyInsListLength = 0;
		if( s == null ) {
			return;
		}
		
		int t1 = n_ImagePanel.ImagePanel.ScaleIndex;
		int t2 = n_ImagePanel.ImagePanel.AScale;
		n_ImagePanel.ImagePanel.ScaleIndex = 10;
		n_ImagePanel.ImagePanel.AScale = n_ImagePanel.ImagePanel.ScaleList[n_ImagePanel.ImagePanel.ScaleIndex];
		
		
		int CurrentY = HeadHeight + InsPadding1 / 2;
		for( int i = 0; i < s.Length; ++i ) {
			
			n_FuncIns.FuncIns funci = new n_FuncIns.FuncIns();
			string ss = s[i];
			string Name = "";
			if( ss.StartsWith( "(无效)" ) ) {
				ss = ss.Remove( 0, 4 );
				Name = "(无效)";
			}
			if( ss == "-" ) {
				Name = ss;
			}
			funci.SetUserValue( Name, null, "?void " + PreType[i] + " " + ss, ModWidth + InsPadding1, CurrentY, 0 );
			
			if( ss == "-" ) {
				funci.Height /= 2;
			}
			
			C_MyInsList[ C_MyInsListLength ] = funci;
			++C_MyInsListLength;
			CurrentY += funci.Height + InsPadding1;
		}
		
		n_ImagePanel.ImagePanel.ScaleIndex = t1;
		n_ImagePanel.ImagePanel.AScale = t2;
	}
	
	//设置表达式集合
	public void SetExp( string[] s, string PreType )
	{
		StartInsY = 0;
		
		List = s;
		MouseOnInsIndex = -1;
		C_MyInsListLength = 0;
		if( s == null ) {
			return;
		}
		
		int t1 = n_ImagePanel.ImagePanel.ScaleIndex;
		int t2 = n_ImagePanel.ImagePanel.AScale;
		n_ImagePanel.ImagePanel.ScaleIndex = 10;
		n_ImagePanel.ImagePanel.AScale = n_ImagePanel.ImagePanel.ScaleList[n_ImagePanel.ImagePanel.ScaleIndex];
		
		
		int CurrentY = HeadHeight + InsPadding1 / 2;
		for( int i = 0; i < s.Length; ++i ) {
			
			n_FuncIns.FuncIns funci = new n_FuncIns.FuncIns();
			string ss = s[i];
			string Name = "";
			if( ss.StartsWith( "(无效)" ) ) {
				ss = ss.Remove( 0, 4 );
				Name = "(无效)";
			}
			if( ss == "-" ) {
				Name = ss;
			}
			//这里不会影响返回结果, 只用于用户呈现
			//funci.SetUserValue( Name, null, "?void " + PreType + " " + ss, InsPadding1, CurrentY, 0 );
			funci.SetUserValue( Name, null, "?void @OPER " + ss, ModWidth + InsPadding1, CurrentY, 0 );
			
			if( ss == "-" ) {
				funci.Height /= 2;
			}
			
			C_MyInsList[ C_MyInsListLength ] = funci;
			++C_MyInsListLength;
			CurrentY += funci.Height + InsPadding1;
		}
		
		n_ImagePanel.ImagePanel.ScaleIndex = t1;
		n_ImagePanel.ImagePanel.AScale = t2;
	}
	
	//重绘事件
	protected override void OnPaint(PaintEventArgs e)
	{
		Graphics g = e.Graphics;
		
		g.SmoothingMode = SmoothingMode.HighSpeed;
		
		//g.TranslateTransform( StartX, StartY );
		
		//填充背景
		g.Clear( Color.White );
		
		//绘制模块列表
		g.FillRectangle( B_Brush, 0, 0, ModWidth, Height );
		g.DrawLine( Pens.Silver, ModWidth-1, 0, ModWidth-1, Height );
		g.SetClip( new Rectangle( 0, 0, ModWidth, Height ) );
		g.TranslateTransform( 0, StartModY );
		
		for( int i = 0; i < ModLength; ++i ) {
			int miny = ModList[ i ].SY;
			
			if( ModList[i] == SelectedMod ) {
				g.FillRectangle( Brushes.White, 0, miny, ModList[i].Width, ModList[i].Height );
				g.DrawLine( Pens.Silver, 0, miny, ModList[i].Width, miny );
				g.DrawLine( Pens.Silver, 0, miny + ModList[i].Height, ModList[i].Width, miny + ModList[i].Height );
				//g.DrawRectangle( Pens.DarkKhaki, 0, miny, ModList[i].Width, ModList[i].Height );
			}
			else if( MouseOnModIndex == i ) {
				g.FillRectangle( Brushes.LightSteelBlue, 0, miny, ModList[i].Width, ModList[i].Height );
			}
			ModList[i].Draw( g );
		}
		g.TranslateTransform( 0, -StartModY );
		g.ResetClip();
		
		if( ModInsPanelVisible ) {
			//绘制按钮列表
			g.TranslateTransform( 0, StartInsY );
			for( int i = 0; i < C_MyInsListLength; ++i ) {
				
				int miny = C_MyInsList[ i ].SY - InsPadding1 / 2;
				if( C_MyInsList[ i ].Name == "-" ) {
					if( i != C_MyInsListLength - 1 ) {
						g.FillRectangle( Brushes.LightGray, ModWidth + 50, miny + (C_MyInsList[ i ].Height + InsPadding1)/2, Width - (ModWidth*2 + 100), 2 );
					}
					continue;
				}
				if( MouseOnInsIndex == i ) {
					g.FillRectangle( Brushes.Gainsboro, ModWidth, miny, Width - ModWidth, C_MyInsList[ i ].Height + InsPadding1 );
					g.DrawRectangle( Pens.SlateGray, ModWidth, miny, Width - ModWidth, C_MyInsList[ i ].Height + InsPadding1 );
				}
				C_MyInsList[ i ].Draw1( g );
			}
			g.TranslateTransform( 0, -StartInsY );
		}
		
		if( Owner.MesText != null ) {
			
			SizeF sf = g.MeasureString( Owner.MesText, GUIset.Font11, Width-ModWidth );
			g.DrawString( Owner.MesText, GUIset.Font11, Brushes.SlateGray, new RectangleF( ModWidth, Height-sf.Height, sf.Width, sf.Height ) );
			
			//n_SG.SG.MString.MeasureSize( Owner.MesText, 11, Width-110, out w, out h );
			//g.DrawString( Owner.MesText, GUIset.Font11, Brushes.SlateGray, 10, Height - 20 );
			//n_SG.SG.MString.DrawAtRectangle( Owner.MesText, Color.SlateGray, 110, 110, Height - h, w, h );
		}
		
		//绘制标题栏
		g.FillRectangle( Brushes.CornflowerBlue, 0, 0, Width, HeadHeight );
		g.DrawString( "指令编辑器", GUIset.Font11, Brushes.White, Width/2-40, 3 );
	}
	
	//鼠标滚轮
	void MyMouseWheel( object sender, MouseEventArgs e)
	{
		if( MouseX > ModWidth && ModInsPanelVisible ) {
			if( e.Delta > 0 ) {
				StartInsY += 50;
			}
			else {
				StartInsY -= 50;
			}
		}
		if( MouseX < ModWidth ) {
			if( e.Delta > 0 ) {
				StartModY += 50;
			}
			else {
				StartModY -= 50;
			}
		}
		
		this.Invalidate();
	}
	
	//鼠标按下事件
	void UserMouseDown( object sender, MouseEventArgs e )
	{
		if( e.Button == MouseButtons.Left ) {
			
			if( e.Y < HeadHeight ) {
				HeadPress = true;
				lastX = e.X;
				lastY = e.Y;
			}
			else {
				LeftPress = true;
				LastInsY = e.Y;
				LastModY = e.Y;
				MoveTick = 0;
				MyClick = true;
			}
		}
		if( e.Button == MouseButtons.Right ) {
			RightPress = true;
		}
		this.Invalidate();
		
		//this.Focus();
	}
	
	//鼠标松开事件
	void UserMouseUp( object sender, MouseEventArgs e )
	{
		if( e.Button == MouseButtons.Left ) {
			LeftPress = false;
			HeadPress = false;
			
			//判断是否点击模块
			if( MyClick && MouseOnModIndex != -1 ) {
				Owner.SelectMod( ModList[MouseOnModIndex].Name );
				SelectedMod = ModList[MouseOnModIndex];
			}
			if( ModInsPanelVisible ) {
				//判断是否点击指令
				if( MyClick && MouseOnInsIndex != -1 && C_MyInsList[ MouseOnInsIndex ].Name != "-" ) {
					//MessageBox.Show( MouseOnIndex + "  ->  " + List[MouseOnIndex] );
					if( ItemSelect != null ) {
						ItemSelect( List[MouseOnInsIndex], MouseOnInsIndex );
					}
				}
			}
		}
		if( e.Button == MouseButtons.Right ) {
			RightPress = false;
		}
		this.Invalidate();
	}
	
	//鼠标移动事件
	void UserMouseMove( object sender, MouseEventArgs e )
	{
		MouseX = e.X;
		MouseY = e.Y;
		
		MouseOnInsIndex = -1;
		MouseOnModIndex = -1;
		
		if( HeadPress ) {
			Location = new Point( Location.X + (e.X - lastX), Location.Y + (e.Y - lastY) );
			return;
		}
		//上下移动取消点击事件
		if( LeftPress ) {
			MoveTick++;
			if( MoveTick > 3 ) {
				MyClick = false;
			}
		}
		if( MouseX > ModWidth && ModInsPanelVisible ) {
			for( int i = 0; i < C_MyInsListLength; ++i ) {
				int miny = StartInsY + C_MyInsList[ i ].SY - InsPadding1 / 2;
				int maxy = StartInsY + C_MyInsList[ i ].SY + C_MyInsList[ i ].Height + InsPadding1 / 2;
				if( MouseY >= miny && MouseY <= maxy ) {
					MouseOnInsIndex = i;
					break;
				}
			}
			//获取选中的指令的说明信息
			if( MouseOnInsIndex != LastInsIndex ) {
				if( MouseOnIndexChanged != null ) {
					MouseOnIndexChanged( MouseOnInsIndex );
				}
			}
			LastInsIndex = MouseOnInsIndex;
			
			//指令上下移动
			if( LeftPress ) {
				StartInsY += e.Y - LastInsY;
				LastInsY = e.Y;
			}
		}
		if( MouseX <= ModWidth ) {
			for( int i = 0; i < ModLength; ++i ) {
				int miny = StartModY + ModList[ i ].SY;
				int maxy = StartModY + ModList[ i ].SY + ModList[ i ].Height;
				if( MouseY >= miny && MouseY <= maxy ) {
					MouseOnModIndex = i;
					break;
				}
			}
			//获取选中的模块的说明信息
			if( MouseOnModIndex != LastModIndex ) {
				//if( MouseOnIndexChanged != null ) {
				//	MouseOnIndexChanged( MouseOnInsIndex );
				//}
			}
			LastInsIndex = MouseOnInsIndex;
			
			//模块上下移动
			if( LeftPress ) {
				StartModY += e.Y - LastModY;
				LastModY = e.Y;
			}
		}
		
		if( RightPress ) {
			
		}
		this.Invalidate();
	}
	
	//====================================================
	
	public class ModeItem
	{
		public string Name;
		
		Image Img;
		public int SX;
		public int SY;
		public int Width;
		public int Height;
		
		//构造函数
		public ModeItem( Image img, string n, int sx, int sy, int w, int h )
		{
			Img = img;
			Name = n;
			
			SX = sx;
			SY = sy;
			Width = w;
			Height = h;
		}
		
		//绘图函数
		public void Draw( Graphics g )
		{
			g.DrawString( Name, GUIset.Font13, Brushes.Black, SX + Height, SY + 11 );
			
			if( Img == null ) {
				return;
			}
			int w = Img.Width;
			int h = Img.Height;
			
			int pad = 5;
			if( w > h ) {
				w = Height - pad;
				h = h * w / Img.Width;
			}
			else {
				h = Height - pad;
				w = w * h / Img.Height;
			}
			g.DrawImage( Img, SX + (Height - w)/2, SY + (Height - h)/2, w, h );
		}
	}
}
}


